//
//  SLVDNSManager.m
//  Objective-C
//
//  Created by S_Line on 2018/5/3.
//  Copyright © 2018年 S_Line. All rights reserved.
//

#import "SLVDNSManager.h"

#import <JLRoutes/JLRoutes.h>

#import "SLRouteTestController.h"
#import "SLDemo_BaseNavController.h"
#import "SLDemo_RuntimeController.h"
#import "SLDemo_KVCController.h"
#import "SLDemo_KVOController.h"
#import "SLMBPDemoController.h"
#import "SLCADemoController.h"
#import "SLCADemoSolidObjectController.h"
#import "SLCAShapeLayerController.h"
#import "SLCATextLayerController.h"
#import "SLCATransformLayerController.h"
#import "SLCAGradientLayerController.h"
#import "SLCAReplicatorLayerController.h"
#import "SLCAScrollLayerController.h"
#import "SLCAEmitterLayerController.h"
#import "SLCAEAGLayerController.h"
#import "SLCATransactionController.h"
#import "SLCAActionController.h"
#import "SLCAPMController.h"
#import "SLCAPropertyAnimationController.h"
#import "SLCAAnimationGroupController.h"
#import "SLCATransitionController.h"
#import "SLCAMediaTimingController.h"
#import "SLManualAnimationController.h"
#import "SLCAAnimationSpeedController.h"
#import "SLCACustomBufferController.h"
#import "SLCATimerAnimationController.h"
#import "SLCAVectorDrawController.h"
#import "SLCADirtyRectController.h"
#import "SLTransitionContainerController.h"
#import "SLTransitionChildController.h"
#import "SLPOPDemoController.h"
#import "SLPOPSpringController.h"
#import "SLPOPDecayController.h"
#import "SLPOPBasicController.h"
#import "SLPopCustomController.h"
#import "SLCACustomDemoController.h"
#import "SLMessageForwardingController.h"
#import "SLMethodSwizzlingController.h"
#import "SLAssociatedObjectController.h"
#import "SLDescriptionController.h"
#import "SLBlockController.h"
#import "SLCircularReferenceController.h"
#import "SLInterview_AnimationController.h"
#import "SLTestController.h"
#import "SLDemo_MJRefreshController.h"
#import "SLAlgorithmController.h"
#import "SLRecursionController.h"
#import "SLTimerController.h"
#import "SLStoreController.h"
#import "SLCollectionDemoController.h"
#import "SLReactiveProgrammingDemoController.h"
#import "SLSessionDownloadTaskController.h"
#import "SLNestedScrollViewController.h"

#import "Animator.h"

@interface SLVDNSManager()<SLTransitionContainerControllerDelegate>

@property (nonatomic, strong) JLRoutes *slocRouter;
@property (nonatomic, strong) NSDictionary *routeTable;

@end
//nebulas
@implementation SLVDNSManager

+ (instancetype)shareInstance {
    static SLVDNSManager *staticVDNSManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (staticVDNSManager == nil) {
            staticVDNSManager = [[SLVDNSManager alloc] init];
        }
    });
    
    return staticVDNSManager;
}

- (instancetype)init {
    self = [super init];
    
    self.slocRouter = [JLRoutes routesForScheme:@"sloc"];
    [self setUpRouter];
    [self loadRouteTable];
    
    return self;
}

#pragma mark ----- 加载本地路由表
- (void)loadRouteTable {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"route" ofType:@"txt"];
    NSError *error = nil;
    NSString *tableString = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
    if (!error) {
        NSDictionary *routeTable = [NSJSONSerialization JSONObjectWithData:[tableString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];
        if (!error) {
            self.routeTable = routeTable;
        } else {
            NSLog(@"routeTableDict解析失败, 请检查数据");
        }
    } else {
        NSLog(@"routeTable解析失败");
    }
}

#pragma mark ----- 通过路由跳转的方法
- (void)openView:(NSString *)k v:(NSString *)v {
    
    if ([k hasPrefix:@"http:"]) {
        NSLog(@"openView: 该打开一个网页控制器 0");
        NSString *urlString = [NSString stringWithFormat:@"%@", k];
        if (v && v.length > 0) {
            urlString = [NSString stringWithFormat:@"%@?%@", urlString, v];
        }
        NSURL *url = [[NSURL alloc] initWithString:urlString];
        if (url) {
            [[UIApplication sharedApplication] openURL:url];
        }
    } else if ([k hasPrefix:@"sloc:"]) {
        NSLog(@"openView: 该打开一个原生页面控制器 0");
        [JLRoutes routeURL:[NSURL URLWithString:[self handleURLWithK:k v:v]]];
    } else {
        NSString *routeK = self.routeTable[k];
        if (!routeK) return;
        
        if ([routeK hasPrefix:@"http:"]) {
            NSLog(@"openView: 该打开一个网页控制器 1");
        } else if ([routeK hasPrefix:@"sloc:"]) {
            NSLog(@"openView: 该打开一个原生页面控制器 1");
            [JLRoutes routeURL:[NSURL URLWithString:[self handleURLWithK:routeK v:v]]];
        } else {
            NSLog(@"未能找到对应的页面, 请检查数据");
        }
    }
}

- (NSString *)handleURLWithK:(NSString *)k v:(NSString *)v {
    
    if (v.length == 0) return k;
    
    if ([k rangeOfString:@"?"].location == NSNotFound) {
        if ([v hasPrefix:@"?"]) {
            return [k stringByAppendingString:v];
        } else {
            return [k stringByAppendingString:[NSString stringWithFormat:@"?%@", v]];
        }
    } else if ([k hasSuffix:@"?"]) {
        if ([v hasPrefix:@"&"]) {
            return [k stringByAppendingString:[v substringFromIndex:1]];
        } else {
            return [k stringByAppendingString:v];
        }
    } else {
        if ([v hasPrefix:@"&"]) {
            return [k stringByAppendingString:v];
        } else {
            return [k stringByAppendingString:[NSString stringWithFormat:@"&%@", v]];
        }
    }
    
    return nil;
}

#pragma mark ----- 页面跳转
- (void)pushVC:(UIViewController *)vc {
    if (self.navigationController) {
        [self.navigationController pushViewController:vc animated:true];
    }
}

#pragma mark ----- 设置路由

- (void)setUpRouter {
    __weak typeof(self) weakSelf = self;
#pragma mark - BaseVC的路由
    [self.slocRouter addRoute:@"g_base_nav" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLDemo_BaseNavController *vc = [SLDemo_BaseNavController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_runtime" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLDemo_RuntimeController *vc = [SLDemo_RuntimeController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_kvc" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLDemo_KVCController *vc = [SLDemo_KVCController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_kvo" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLDemo_KVOController *vc = [SLDemo_KVOController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_mbp" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLMBPDemoController *vc = [SLMBPDemoController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_test" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLTestController *vc = [SLTestController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_timer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLTimerController *vc = [SLTimerController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_collectionview" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCollectionDemoController *vc = [SLCollectionDemoController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_download" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLSessionDownloadTaskController *vc = [SLSessionDownloadTaskController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_nestedscrollview" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLNestedScrollViewController *vc = [SLNestedScrollViewController new];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
#pragma mark ----- CoreAnimation
    [self.slocRouter addRoute:@"g_demo_ca" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCADemoController *vc = [[SLCADemoController alloc] initWithNibName:@"SLCADemoController" bundle:nil];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_solid_object" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCADemoSolidObjectController *vc = [[SLCADemoSolidObjectController alloc] initWithNibName:@"SLCADemoSolidObjectController" bundle:nil];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_shape_layer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAShapeLayerController *vc = [[SLCAShapeLayerController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_text_layer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCATextLayerController *vc = [[SLCATextLayerController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_transform_layer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCATransformLayerController *vc = [[SLCATransformLayerController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_gradient_layer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAGradientLayerController *vc = [[SLCAGradientLayerController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_replicator_layer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAReplicatorLayerController *vc = [[SLCAReplicatorLayerController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_scroll_layer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAScrollLayerController *vc = [[SLCAScrollLayerController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_emitter_layer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAEmitterLayerController *vc = [[SLCAEmitterLayerController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_eag_layer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAEAGLayerController *vc = [[SLCAEAGLayerController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_transaction" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCATransactionController *vc = [[SLCATransactionController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_action" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAActionController *vc = [[SLCAActionController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_pm" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAPMController *vc = [[SLCAPMController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_property_animation" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAPropertyAnimationController *vc = [[SLCAPropertyAnimationController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_animation_group" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAAnimationGroupController *vc = [[SLCAAnimationGroupController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_transition" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCATransitionController *vc = [[SLCATransitionController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_media_timing" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAMediaTimingController *vc = [[SLCAMediaTimingController alloc] initWithNibName:@"SLCAMediaTimingController" bundle:nil];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_manual_animation" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLManualAnimationController *vc = [[SLManualAnimationController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_animation_speed" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAAnimationSpeedController *vc = [[SLCAAnimationSpeedController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_custom_buffer" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCACustomBufferController *vc = [[SLCACustomBufferController alloc] initWithNibName:@"SLCACustomBufferController" bundle:nil];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_timer_frame" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCATimerAnimationController *vc = [[SLCATimerAnimationController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_vector_draw" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCAVectorDrawController *vc = [[SLCAVectorDrawController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_dirty_rect" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCADirtyRectController *vc = [[SLCADirtyRectController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_ca_custom_demo" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCACustomDemoController *vc = [[SLCACustomDemoController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    // 转场动画
    [self.slocRouter addRoute:@"g_demo_transition_learn" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        NSMutableArray *childViewControllers = [NSMutableArray new];
        NSArray *configurations = @[
                                    @{@"title": @"first", @"color": [UIColor redColor]},
                                    @{@"title": @"second", @"color": [UIColor greenColor]},
                                    @{@"title": @"third", @"color": [UIColor blueColor]}
                                    ];
        for (NSDictionary *dict in configurations) {
            SLTransitionChildController *childVC = [[SLTransitionChildController alloc] init];
            childVC.title = dict[@"title"];
            childVC.themeColor = dict[@"color"];
            childVC.tabBarItem.image = [UIImage imageNamed:dict[@"title"]];
            childVC.tabBarItem.selectedImage = [UIImage imageNamed:[dict[@"title"] stringByAppendingString:@"Selected"]];
            
            [childViewControllers addObject:childVC];
        }
        
        
        SLTransitionContainerController *vc = [[SLTransitionContainerController alloc] initWithViewControllers:childViewControllers];
//        vc.delegate = weakSelf;
        [weakSelf pushVC:vc];
        
        return true;
    }];
    [self.slocRouter addRoute:@"g_demo_store" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLStoreController *vc = [[SLStoreController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
#pragma mark ----- 第三方库
    // pop的动画库
    [self.slocRouter addRoute:@"g_demo_pop" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        NSMutableArray *vcs = [NSMutableArray new];
        SLPOPSpringController *springVC = [[SLPOPSpringController alloc] init];
        springVC.title = @"Spring";
        SLPOPDecayController *decayVC = [[SLPOPDecayController alloc] init];
        decayVC.title = @"Decay";
        SLPOPBasicController *basicVC = [[SLPOPBasicController alloc] init];
        basicVC.title = @"Basic";
        SLPopCustomController *customVC = [[SLPopCustomController alloc] init];
        customVC.title = @"Custom";
        [vcs addObject:springVC];
        [vcs addObject:decayVC];
        [vcs addObject:basicVC];
        [vcs addObject:customVC];
        
        SLPOPDemoController *vc = [[SLPOPDemoController alloc] init];
        vc.viewControllers = [vcs copy];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    // MJRefresh
    [self.slocRouter addRoute:@"g_demo_mjrefresh" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        SLDemo_MJRefreshController *vc = [[SLDemo_MJRefreshController alloc] initWithNibName:@"SLDemo_MJRefreshController" bundle:nil];
        [weakSelf pushVC:vc];
        return true;
    }];
    
    // ReactiveObjC
    [self.slocRouter addRoute:@"g_demo_reactive_programming" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        SLReactiveProgrammingDemoController *vc = [[SLReactiveProgrammingDemoController alloc] init];
        [weakSelf pushVC:vc];
        return true;
    }];
#pragma mark ----- 书籍
    // Effective Objective-C
    [self.slocRouter addRoute:@"g_demo_eoc_message_forwarding" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLMessageForwardingController *vc = [[SLMessageForwardingController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_eoc_method_swizzling" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLMethodSwizzlingController *vc = [[SLMethodSwizzlingController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_eoc_associated_object" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLAssociatedObjectController *vc = [[SLAssociatedObjectController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_eoc_description" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLDescriptionController *vc = [[SLDescriptionController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    [self.slocRouter addRoute:@"g_demo_eoc_block" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLBlockController *vc = [[SLBlockController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
    // 面试
    [self.slocRouter addRoute:@"g_demo_interview_circular_reference" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLCircularReferenceController *vc = [[SLCircularReferenceController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    [self.slocRouter addRoute:@"g_demo_interview_animation" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLInterview_AnimationController *vc = [[SLInterview_AnimationController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    
#pragma mark ----- 算法
    [self.slocRouter addRoute:@"g_demo_algorithm" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLAlgorithmController *vc = [[SLAlgorithmController alloc] initWithNibName:@"SLAlgorithmController" bundle:nil];
        [weakSelf pushVC:vc];
        
        return true;
    }];
    [self.slocRouter addRoute:@"g_demo_recursion" handler:^BOOL(NSDictionary<NSString *,id> * _Nonnull parameters) {
        
        SLRecursionController *vc = [[SLRecursionController alloc] init];
        [weakSelf pushVC:vc];
        
        return true;
    }];
}

- (id<UIViewControllerAnimatedTransitioning>)containerViewController:(SLTransitionContainerController *)containerController animationControllerForTransitionFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
    return [[Animator alloc] init];
}

@end
